# -*- coding: utf-8 -*- 
"""
Created by hcx on 17-6-23 下午4:14.
@author: 胡超翔
"""
# 描述:
# V1 WZJ 2016-12-19 CallBack重写封装api基本功能,用于console输出

import json
import logging

from ansible import constants as C
from ansible.plugins.callback.default import CallbackModule

from autodeploy.apps.operation.views import create_log

logger = logging.getLogger(__name__)

try:
    from __main__ import display
except ImportError:
    from ansible.utils.display import Display
    
    display = Display()


class YunweiCallback(CallbackModule):
    """重写console输出日志"""
    
    def __init__(self, operation_log, *args):
        super(YunweiCallback, self).__init__()
        self.result = {'success': {'ok': [], 'change': [], 'fact': []}, 'fatal': [], 'unreachable': []}
        self.operation_log = operation_log

    # 重写2.0版本正确stdout
    def v2_runner_on_ok(self, result):
        # 获得机器数据
        logger.info('run and get ansible-playbook result:**********************')
        if self._play.strategy == 'free' and self._last_task_banner != result._task._uuid:
            self._print_task_banner(result._task)
        
        self._clean_results(result._result, result._task.action)
        delegated_vars = self._dump_results(result._result)
        self._clean_results(result._result, result._task.action)
        if result._task.action in ('include', 'include_role'):
            return
        elif result._result.get('changed', False):
            if delegated_vars:
                # 自定义输出
                zdy_msg = self.zdy_stdout(json.loads(delegated_vars))
                if zdy_msg:
                    msg = "changed: [%s]%s" % (result._host.get_name(), zdy_msg)
                else:
                    msg = "changed: [%s -> %s]" % (result._host.get_name(), delegated_vars)
            else:
                msg = "changed: [%s]" % result._host.get_name()
            color = C.COLOR_CHANGED
            # self.result['success']['change'] = json.loads(delegated_vars)
            create_log(self.operation_log, result=delegated_vars, detail_status='success')
            self.result['success']['change'].append(json.loads(delegated_vars))
        # 判断是否是第一步 setup
        elif result._result.get('ansible_facts', False):
            msg = "ok: [ %s | %s ]" % (str(result._host), delegated_vars)
            color = C.COLOR_OK
            # self.result['success']['fact'] = result._result.get('ansible_facts')
            create_log(self.operation_log, result=delegated_vars, detail_status='success')
            self.result['success']['fact'].append(result._result.get('ansible_facts'))
        else:
            if delegated_vars:
                # 自定义输出
                zdy_msg = self.zdy_stdout(json.loads(delegated_vars))
                if zdy_msg:
                    msg = "ok: [%s]%s" % (result._host.get_name(), zdy_msg)
                else:
                    msg = "ok: [%s -> %s]" % (result._host.get_name(), delegated_vars)
            else:
                msg = "ok: [%s]" % result._host.get_name()
            color = C.COLOR_OK
            # self.result['success']['ok'] = json.loads(delegated_vars)
            self.result['success']['ok'].append(json.loads(delegated_vars))
            #创建日志详情
            create_log(self.operation_log, result=delegated_vars, detail_status='success')
        if result._task.loop and 'results' in result._result:
            self._process_items(result)
        else:
            self._display.display(msg, color=color)
        self._handle_warnings(result._result)
        logger.info("result:%s" % result)

    def v2_runner_on_failed(self, result, ignore_errors=False):
        super(YunweiCallback, self).v2_runner_on_failed(result, ignore_errors)
        self.result['fatal'].append(self._dump_results(result._result))
        # self.result['fatal']=(self._dump_results(result._result))
        create_log(self.operation_log, result=self._dump_results(result._result), status='defeat',detail_status='failed')
        logger.info("result:%s" % result)

    def v2_runner_on_unreachable(self, result):
        super(YunweiCallback, self).v2_runner_on_unreachable(result)
        # self.result['unreachable'] = self._dump_results(result._result)
        self.result['unreachable'].append(self._dump_results(result._result))
        create_log(self.operation_log, result=self._dump_results(result._result), status='defeat',detail_status='failed')
        logger.info("result:%s" % result)

    # 自定义输出,格式清晰一些
    def zdy_stdout(self, result):
        logger.info("result:%s" % result)
        msg = ''
        if result.get('delta', False):
            msg += u'执行时间:%s' % result['delta']
        if result.get('cmd', False):
            msg += u'执行命令:%s' % result['cmd']
        if result.get('stderr', False):
            msg += u'错误输出:%s' % result['stderr']
        if result.get('stdout', False):
            msg += u'正确输出:%s' % result['stdout']
        if result.get('warnings', False):
            msg += u'警告:%s' % result['warnings']
        return msg
